from typing import Dict, Annotated, Any
from fastapi import APIRouter, Body, HTTPException
from starlette.responses import StreamingResponse, JSONResponse
import io

from server.audio_server import text2speech
from server.image_server import create_image
from server.video_server import (check_image_for_video, generate_action_for_video,
                               create_video_by_type, generate_3d_role_for_video)

router = APIRouter(prefix="/ai", tags=["媒体处理"])

@router.post("/create_images")
async def create_images(json_post: Annotated[Dict[str, Any], Body()]):
    try:
        description = json_post.get("description")
        negative_prompt = """..."""  # 保持原有的negative_prompt
        prompt_extend = json_post.get("prompt_extend", True)
        watermark = json_post.get("watermark", False)
        sketch_image_url = json_post.get("sketch_image_url")
        base_image_url = json_post.get("base_image_url")
        mask_image_url = json_post.get("base_image_url")
        
        extra_input = None
        if base_image_url and sketch_image_url:
            extra_input = {
                "base_image_url": base_image_url,
                "mask_image_url": mask_image_url
            }
        
        result_data = create_image(description, negative_prompt=negative_prompt,
                                 sketch_image_url=sketch_image_url,
                                 extra_input=extra_input,
                                 prompt_extend=prompt_extend)
        return JSONResponse(status_code=200, content=result_data)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@router.post("/text_to_speech", summary="文字转语音接口")
async def text_to_speech(json_post: Annotated[Dict[str, Any], Body()]):
    try:
        text = json_post.get("text", "")
        return StreamingResponse(
            io.BytesIO(text2speech(text)),
            media_type="audio/wav"
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/ai/image2video_check", summary="检查图片是否适合生成视频", tags=['doc'])
async def image2video_check(json_post: Annotated[Dict[str, Any], Body()]):
    """
    检查提供的图片是否适合用于视频生成
    """
    try:
        image_url = json_post.get("image_url")
        # "animate-anyone-detect-gen2" 舞动人像
        type = json_post.get("type")
        if not type:
            raise HTTPException(status_code=400, detail="type参数错误")
        if not image_url:
            raise HTTPException(status_code=400, detail="缺少image_url参数")

        result = check_image_for_video(type=type, image_url=image_url, )
        return JSONResponse(status_code=200, content=result)

    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/ai/generate_video_action", summary="检查图片是否适合生成视频", tags=['doc'])
async def generate_video_action(json_post: Annotated[Dict[str, Any], Body()]):
    """
    提取视频动作
    """
    try:
        video_url = json_post.get("video_url")
        if not video_url:
            raise HTTPException(status_code=400, detail="缺少video_url参数")

        template_id = generate_action_for_video(video_url)
        return JSONResponse(status_code=200, content=template_id)

    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/ai/create_action_video_by_video", summary="舞动人像-根据图片和动作生成视频", tags=['doc'])
async def create_action_video_by_video(json_post: Annotated[Dict[str, Any], Body()]):
    """
    将图片人物实现视频动作
    """
    try:
        image_url = json_post.get("image_url")
        video_url = json_post.get("video_url")
        type = json_post.get("type")

        if type=="VIDEO":
            result = create_video_by_type(type=type, json_post=json_post)
            return JSONResponse(status_code=200, content=result)
        else:
            if type == "Motion":
                check_result = check_image_for_video(type=type, video_url=video_url)
            else:
                check_result = check_image_for_video(type=type, image_url=image_url, )

            if check_result["output"]["check_pass"]:
                if type == "ANIMATE" and video_url:
                    template_id = generate_action_for_video(video_url)
                    json_post["template_id"] = template_id
                elif type == "EMO":
                    face_bbox = check_result["output"]["face_bbox"]
                    ext_bbox = check_result["output"]["ext_bbox"]
                    if face_bbox and ext_bbox and ext_bbox:
                        json_post["face_bbox"] = face_bbox
                        json_post["ext_bbox"] = ext_bbox
                    else:
                        raise HTTPException(status_code=400, detail="EMO检测参数丢失")
                elif type == "Motion":
                    detected = check_result["output"]["detected"]
                    frame_index = check_result["output"]["frame_index"]
                    bbox = check_result["output"]["bbox"]
                    ply_url = generate_3d_role_for_video(image_url)
                    if detected and frame_index and bbox:
                        json_post["detected"] = detected
                        json_post["frame_index"] = frame_index
                        json_post["replacement_id"] = [ply_url]
                    else:
                        raise HTTPException(status_code=400, detail="Motion检测参数丢失")
                result = create_video_by_type(type=type, json_post=json_post)
                return JSONResponse(status_code=200, content=result)
            else:
                raise HTTPException(status_code=400, detail="图片不适合生成视频")
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))